package org.example.service;

import org.example.model.Session;
import org.example.storage.SessionStorage;

import java.security.SecureRandom;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Map;
import java.util.Optional;

/**
 * 会话服务实现 - 完整的会话管理逻辑
 */
public class SessionService {
    private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    private static final int SESSION_KEY_LENGTH = 7;
    private static final int SESSION_DURATION_MINUTES = 10;
    private static final int MAX_SESSION_GENERATION_ATTEMPTS = 5;

    private final SessionStorage sessionStorage;
    private final SecureRandom random;

    // 统计信息
    private long sessionCreationCount = 0;
    private long sessionValidationCount = 0;
    private long failedValidations = 0;

    public SessionService(SessionStorage sessionStorage) {
        this.sessionStorage = sessionStorage;
        this.random = new SecureRandom();
    }

    public void shutdown() {
            System.out.println("Shutting down SessionService...");
    }

    /**
     * 获取一个会话
     * */
    public String getOrCreateSession(int customerId) {

        // 首先检查是否已有有效会话
        Optional<Session> existingSession = sessionStorage.findSessionByCustomerId(customerId);
        if (existingSession.isPresent()) {
            sessionCreationCount++; // 虽然是获取，但也算一次会话操作
            return existingSession.get().getSessionKey();
        }

        // 创建新会话
        String sessionKey = generateUniqueSessionKey();
        Instant expiryTime = Instant.now().plus(SESSION_DURATION_MINUTES, ChronoUnit.MINUTES);

        Session newSession = new Session(sessionKey, customerId, expiryTime);
        sessionStorage.saveSession(newSession);

        sessionCreationCount++;

        System.out.println("Created new session for customer " + customerId + ": " + sessionKey);

        return sessionKey;
    }

    public boolean isValidSession(String sessionKey) {

        boolean isValid = sessionStorage.findSessionByKey(sessionKey).isPresent();
        sessionValidationCount++;

        if (!isValid) {
            failedValidations++;
        }

        return isValid;
    }

    public Optional<Integer> getCustomerIdBySession(String sessionKey) {
        return sessionStorage.findSessionByKey(sessionKey)
                .map(Session::getCustomerId);
    }

    public boolean invalidateSession(String sessionKey) {
        Optional<Session> session = sessionStorage.findSessionByKey(sessionKey);
        if (session.isPresent()) {
            boolean removed = sessionStorage.removeSession(
                    session.get().getCustomerId(),
                    sessionKey
            );

            if (removed) {
                System.out.println("Invalidated session: " + sessionKey);
            }

            return removed;
        }

        return false;
    }

    /**
     * 获取服务统计信息
     */
    public Map<String, Object> getServiceStatistics() {
        Map<String, Object> stats = new java.util.HashMap<>();
        stats.put("sessionCreationCount", sessionCreationCount);
        stats.put("sessionValidationCount", sessionValidationCount);
        stats.put("failedValidations", failedValidations);
        stats.put("successRate", calculateSuccessRate());

        return stats;
    }

    /**
     * 延长会话有效期
     */
    public boolean extendSession(String sessionKey, int additionalMinutes) {

        Optional<Session> sessionOpt = sessionStorage.findSessionByKey(sessionKey);
        if (sessionOpt.isPresent()) {
            Session session = sessionOpt.get();
            Instant newExpiryTime = Instant.now().plus(additionalMinutes, ChronoUnit.MINUTES);

            // 创建新会话对象并替换
            Session extendedSession = new Session(
                    session.getSessionKey(),
                    session.getCustomerId(),
                    newExpiryTime
            );

            sessionStorage.saveSession(extendedSession);
            System.out.println("Extended session " + sessionKey + " by " + additionalMinutes + " minutes");

            return true;
        }

        return false;
    }

    /**
     * 生成唯一的会话密钥
     */
    private String generateUniqueSessionKey() {
        for (int attempt = 0; attempt < MAX_SESSION_GENERATION_ATTEMPTS; attempt++) {
            String sessionKey = generateSessionKey();

            // 检查是否已存在
            if (!sessionStorage.findSessionByKey(sessionKey).isPresent()) {
                return sessionKey;
            }
        }

        throw new RuntimeException("Failed to generate unique session key after " +
                MAX_SESSION_GENERATION_ATTEMPTS + " attempts");
    }

    /**
     * 生成随机会话密钥
     */
    private String generateSessionKey() {
        StringBuilder sb = new StringBuilder(SESSION_KEY_LENGTH);
        for (int i = 0; i < SESSION_KEY_LENGTH; i++) {
            int index = random.nextInt(CHARACTERS.length());
            sb.append(CHARACTERS.charAt(index));
        }
        return sb.toString();
    }

    /**
     * 计算验证成功率
     */
    private double calculateSuccessRate() {
        if (sessionValidationCount == 0) {
            return 0.0;
        }
        return ((double) (sessionValidationCount - failedValidations) / sessionValidationCount) * 100;
    }

}